﻿
//表单
if (F.Form) {
    $.extend(F.Form.prototype, {
        initData: {},
        //字段只读（是否只读，字段集合）
        fieldReadonly: function (b, fields) {
            var t = this;
            b = b || false;
            function f(k, rb, list) {
                if (k.items) {
                    $.each(k.items, function (i, v) {
                        if (list) {
                            if (v.setReadonly && list.indexOf(v.id) >= 0) {
                                if (rb) {
                                    $(v.el).find("input.f-field-textbox").addClass("fieldReadonly");
                                    $(v.el).find("textarea.f-field-textbox").addClass("fieldReadonly");
                                } else {
                                    $(v.el).find("input.f-field-textbox").removeClass("fieldReadonly");
                                    $(v.el).find("textarea.f-field-textbox").removeClass("fieldReadonly");
                                }
                                v.setReadonly(rb);
                            }
                            f(v, rb, list);
                        } else {
                            if (v.setReadonly) {
                                if (rb) {
                                    $(v.el).find("input.f-field-textbox").addClass("fieldReadonly");
                                    $(v.el).find("textarea.f-field-textbox").addClass("fieldReadonly");
                                } else {
                                    $(v.el).find("input.f-field-textbox").removeClass("fieldReadonly");
                                    $(v.el).find("textarea.f-field-textbox").removeClass("fieldReadonly");
                                }
                                v.setReadonly(rb);
                            }
                            f(v, rb);
                        }
                    })
                }
            }
            if (fields && $.isArray(fields)) {
                f(t, b, fields);
            } else {
                f(t, b);
            }
        },
        //只读
        setReadOnly: function (cols) {
            var t = this;
            var c = [];
            //得到对应data的ID
            var datael = $(t.el).find(".f-field[data]");
            $.each(datael, function (i, v) {
                if (cols.indexOf($(v).attr('data')) >= 0) {
                    c.push($(v).attr('id'));
                    F.ui[$(v).attr('id')].setEmptyText('');
                }
            });
            t.fieldReadonly(true, c);
            return t;
        },
        //得到数据 （是否验证）
        getdata: function (isv) {
            var t = this;
            var data = t.initData || {};
            if (isv) {
                if (!F.validateForm(t.id, '_self', false, false)) {
                    return false;
                }
            }
            var datael = $(t.el).find(".f-field[data]");
            $.each(datael, function (i, v) {
                var id = $(v).attr("id");
                var d = $(v).attr("data").replace("Data_", "");
                if (d) {
                    data[d] = F.ui[id].getValue();
                    if (F.isARR(data[d])) {
                        data[d] = data[d].join(",");
                    }
                    if (F.ui[id].type == 'datepicker') {
                        data[d] = F.ui[id].getText();
                    }
                }
            });
            var dataid = $(t.el).attr("DataID");
            data[dataid] = F.ui[t.id].DataID;
            if (t.hideData) { data = Object.assign(data, t.hideData); }
            return data;
        },
        //设置数据
        setdata: function (data, update = false) {
            var t = this;
            if (!update) {
                t.initData = data;
            } else {
                t.initData = Object.assign(t.initData, data);
            }
            var datael = $(t.el).find(".f-field[data]");
            var dataid = $(t.el).attr("DataID");
            if (dataid && dataid != '' && t.initData[dataid]) {
                F.ui[t.id].beforDataID = F.ui[t.id].DataID;
                F.ui[t.id].DataID = t.initData[dataid];
            };
            $.each(datael, function (i, v) {
                var id = $(v).attr("id");
                //console.log('id>', $(v));
                var d = $(v).attr("data").replace("Data_", "");
                if (d && !F.isUND(t.initData[d])) {
                    F.ui[id].setValue(t.initData[d]);
                }
                if (d && d.includes('.')) {
                    let ds = d.split('.');
                    let v = t.initData;
                    ds.forEach((i) => {
                        v = v && v[i];
                    });
                    !F.isUND(v) && F.ui[id].setValue(v);
                }
            })
            return t;
        },
        //保存数据
        savedata: function (backurl, ex) {
            var t = this;
            if (!F.isSTR(backurl) && !ex) {
                ex = backurl;
            }
            //得到表单数据（是否验证）
            var d = F.ui[t.id].getdata(true);
            if (!d) return;
            var dataid = $(t.el).attr("DataID");
            d[dataid] = F.ui[t.id].DataID;
            var savems = {
                ms: JSON.stringify(d)
            };
            if (ex) {
                savems = $.extend(savems, ex);
            }
            if (F.isSTR(backurl)) {
                F.doPostBack(backurl, savems);
            } else {
                try {
                    eval('var href = window.pburl;');
                    if (href) {
                        F.doPostBack(href + "/" + t.id + 'save', savems);
                    } else {
                        F.doPostBack(t.id + 'save', savems);
                    }
                }
                catch (e) { }
            }
            return t;
        },
        //保存数据
        savedataAsync: function (backurl, ex) {
            var t = this;
            if (!F.isSTR(backurl) && !ex) {
                ex = backurl;
            }
            //得到表单数据（是否验证）
            var d = F.ui[t.id].getdata(true);
            if (!d) return;
            var dataid = $(t.el).attr("DataID");
            d[dataid] = F.ui[t.id].DataID;
            var savems = {
                ms: JSON.stringify(d)
            };
            if (ex) {
                savems = $.extend(savems, ex);
            }
            if (F.isSTR(backurl)) {
                return F.doPostBackP({ url: backurl, params: savems });
            } else {
                try {
                    eval('var href = window.pburl;');
                    if (href) {
                        return F.doPostBackP({ url: href + "/" + t.id + 'save', params: savems });
                    } else {
                        return F.doPostBackP({ url: t.id + 'save', params: savems });
                    }
                }
                catch (e) { }
            }
        }
    });
}

//表单字段
if (F.Field) {
    $.extend(F.Field.prototype, {
        //增加后缀
        Append(h) {
            let t = this;
            let suffix = $("<div>").addClass("f-field-body-cell-suffix").append(h);
            let appenddom = $("<div>").addClass("f-field-body-cell-rightpart").append(suffix);
            //bodyEl上册是 f-field-body-cell-centerpart
            //增加一层f-field-body-cell-rightpart f-field-body-cell-suffix
            //再上层是f-field-body-cell-table
            t.bodyEl.parent().addClass("f-field-body-cell-centerpart").removeClass("f-field-body-cell-inner").parent()
                .addClass("f-field-body-cell-table").removeClass("f-field-body-cell").append(appenddom);
            return t;
        },
        //注册添加后的事件
        AppendRendered() {
            let t = this;
            let btn = `<div id='${t.id}_btn'></div>`;
            t.Append(btn);
            t.trigger("AppendRendered", [$(`${t.id}_btn`), t]);
        },
        /**
         * 添加后缀按钮
         * F.ui.XX.AppendBtn("测试", (btn,t) => {});
         * @param {any} title 标题
         * @param {any} fun 点击回调(btn当前按钮，t当前控件)
         */
        AppendBtn(title, fun) {
            let t = this;
            let divid = GetGuid();
            t.Append(`<div id='${divid}'></div>`);
            F.create({
                type: 'button', renderTo: `#${divid}`, text: `${title}`,
                scale: 'small',
                handler: function () {
                    doCallback(fun, [this, t]);
                },
                listeners: {
                    render: function () {
                        t.btn = this;
                    }
                }
            });
            return t;
        },
        AppendCss() {
            let t = this;
            //btn不显示就不改了
            let btn = t.btn;
            if (!t.btn.el.is(':hidden')) {
                //t.el.find(".f-field-body-cell-table input").css({
                //    "padding-right": "23px", "border-right": "none"
                //});
            }
        }
    });
}

//lable
if (F.Label) {
    $.extend(F.Label.prototype, {
        //增加清空按钮 只在tag下有效
        setTagClear() {
            let t = this;
            if (t.el.hasClass('tag')) {
                let tagc = $('<i class="f-field-triggerbox-icon f-icon f-iconfont f-triggerbox-trigger1 f-triggericon-clear" style="display: inline-block;"></i>');
                t.bodyEl.append(tagc);
                t.tagClear = tagc;
                t.tagClear.on('click', () => {
                    this.trigger("tagClearClick", [tagc]);
                });
            }
            return t;
        }
    });
}

//树
if (F.Tree) {
    $.extend(F.Tree.prototype, {
        //模拟点击行
        rowClick(i = 0) {
            let t = this;
            $(t.el).find(".f-tree-node").eq(i).click();
            return t.getSelectedNode();
        },
        animateExpanded() {
            let t = this;
            if (t.Expandedanimate) { return; }
            let article = document.getElementById(`${t.id}`);
            let observer = new MutationObserver(mutations => {
                mutations.forEach(mutation => {
                    let tar = $(mutation.target);
                    //console.log('mutation.oldValue>', mutation.oldValue);
                    if (mutation.oldValue &&
                        mutation.oldValue.indexOf("f-expanded") <= 0
                        && tar.hasClass("f-expanded")) {
                        let nodeid = tar.data("nodeid");
                        let trgroup = $(`#${t.id} [data-parentnodeid='${nodeid}']`);
                        let inner = $(`#${t.id} [data-parentnodeid='${nodeid}'] td>.f-tree-group-inner`);
                        //trgroup.animateCss(`fadeIn`);
                        let it = inner.height();
                        if (it == 0) { return; }
                        //trgroup.addClass("f-tree-group-animating");
                        inner.css({
                            height: 0,
                            opacity: 0
                        });
                        setTimeout(() => {
                            trgroup.one("transitionend", () => {
                                //console.log('transitionend>');
                                trgroup.removeClass("f-tree-group-animating");
                                inner.css({
                                    height: "",
                                    opacity: ""
                                });
                            });
                            trgroup.addClass("f-tree-group-animating");
                            inner.css({
                                height: it,
                                opacity: 1
                            })
                        }, 30);
                    }
                });
            });
            observer.observe(article, {
                'childList': true,//子集
                'attributeFilter': ['class'],//监听的属性
                'attributes': true,//
                'attributeOldValue': true,//监听old值
                'subtree': true//子集
            });
            t.Expandedanimate = true;
        }
    });
}

//表格
if (F.Grid) {
    $.extend(F.Grid.prototype, {
        editWidth: 800,//修改窗口的宽
        editHeight: 650,//修改窗口的高
        editTitle: "编辑",
        //更新行
        updaterow: function (data, rowid) {
            var t = this;
            if (!$.isArray(data)) {
                data = eval('(' + data + ')');
            }
            rowid = rowid || data[t.idField];
            for (var d in data) {
                t.updateCellValue(rowid, d, data[d]);
            }
            return t;
        },
        //显示编辑页面
        showEdit: function (b, data, title, w, h) {
            var t = this;

            let _reg = Math.random();
            let MenuId = F.queryString("MenuId");
            let url = setIframeUrl(t.WindowUrl, { MenuId });
            if (b) {
                var selectids = F.ui[t.id].getSelectedRows();
                if (selectids.length != 1) {
                    notifyEx("请选择一行进行编辑");
                    return;
                }
                let id = selectids[0];
                url = setIframeUrl(url, { id });
            }
            if (data) {
                url = setIframeUrl(url, data);
            }
            t.Window.show(url);
            return t.Window;
            //F.ui[t.id + 'GridEdit'].show(editurl, title, w, h);
        },
        //重置页码
        relodenub: function () {
            var t = this;
            var nub = 0;
            //重置页码
            $.each($('#' + t.id + ' .f-grid-row'), function (i) {
                if (!$(this).hasClass("f-hidden")) {
                    var b = $(this).find('.f-grid-rownumberfield .f-grid-cell-inner');
                    b.html(nub + 1);
                    nub++;
                }
            });
            return t;
        },
        //数据的扁平
        getValues() {
            let data = [];
            data = this.data.map(item => {
                let d = {};
                d[this.idField] = item.id;
                Object.assign(d, {
                    ...item.values
                });
                return d;
            })
            return data;
        },
        //模拟点击行
        rowClick(i = 0, btn) {
            let t = this;
            $(t.el).find(".f-grid-bodyct table tr").eq(i).click();
            if (btn) {
                $(t.el).find(`.f-grid-bodyct table tr [data-type='${btn}']`).eq(i).click();
            }
            return t;
        },
        //刷新继续选中
        dataloadSelect() {
            const t = this;
            t.on('selectionchange', function () {
                //notifyEx(`改了${F.ui.Grid1.getSelectedRow()}`);
                t.localSelect = t.getSelectedRow();
            });
            t.on('dataload', function () {
                if (t.localSelect) {
                    let el = t.getRowEl(t.localSelect);
                    if (el.length == 0) {
                        t.localSelect = null;
                    }
                    else {
                        t.selectRow(t.localSelect, { scrollTo: true });
                    }
                }
            });
        },

        /**拼接数据[[], []]*/
        dataSource(dt) {
            const t = this;
            const fields = t.fields;
            let data = dt.map(row => {
                return fields.map(d => {
                    let v = row;
                    let ds = d.split('.');
                    ds.forEach((i) => {
                        v = v && v[i];
                    });
                    return v;
                });
            });
            t.loadData(data);
            return t;
        },
        /**
         * 传入列名 从前端合并单元格，行合并
         * @param {Array} cols 列集合
         */
        mergeColumns(cols) {
            if (F.isSTR(cols)) { cols = [cols] };
            const t = this;
            const gettd = (i, tdel) => {
                let td = tdel[i];
                let next = tdel[i + 1];
                if (next && td.innerHTML == next.innerHTML) {
                    $(next).hide();
                    return 1 + gettd(i + 1, tdel);
                }
                return 0;
            };
            let el = t.bodyEl;
            cols.forEach((col) => {
                let tdel = el.find(`.f-grid-cell-${col}`);
                for (let i = 0; i < tdel.length; i++) {
                    let td = tdel[i];
                    let t = gettd(i, tdel);
                    if (t > 0) {
                        i += t;
                        $(td).attr("rowspan", t + 1);
                    }
                }
            });
            return t;
        },
        /**滚动表格 */
        rollData() {
            let t = this;
            //复制元素
            (() => {
                let body = t.el.find(".f-grid-bodyct");
                body.css("overflow", "hidden");
                let table = body.find("table");
                let table1 = table.clone();
                let table2 = table.clone();
                table.css({
                    "position": "absolute",
                    //"transition":"top .1s",
                });
                table1.css({
                    "top": "100%",
                    "bottom": "auto",
                    "position": "absolute",
                });
                table2.css({
                    "top": "auto",
                    "bottom": "100%",
                    "position": "absolute",
                });
                table.append(table1);
                table.append(table2);

                t.roll1 = table1;
                t.roll2 = table2;
            })();

            //准备参数
            (() => {
                t.roll = true;
                //canroll 是否滚动
                Object.defineProperty(t, "canroll",
                    {
                        get: function () {
                            let _body = t.el.find(".f-grid-bodyct");
                            let _table = _body.find("table").eq(0);
                            if (_body.height() > _table.height()) return false;
                            if (!t.roll) return false;
                            return true;
                        }
                    });

                //最大高度 正负边界等于table的高度
                Object.defineProperty(t, "rollmax",
                    {
                        get: function () {
                            return t.el.find(".f-grid-bodyct").find("table").height();
                        }
                    });

                //rolltop 控制当前top
                Object.defineProperty(t, "rolltop",
                    {
                        get: function () {
                            if (typeof t._rolltop === "undefined") {
                                t._rolltop = 0;
                            }
                            t._rolltop = t._rolltop - .5;
                            if (t._rolltop < 0 - t.rollmax) {
                                t._rolltop = t.rollmax;
                            }
                            return t._rolltop;
                        }
                    });
            })();

            //启动监听
            t.openObserver();
            t.on("observer", function (e, els) {
                els.forEach(function (mutation) {
                    let tar = $(mutation.target);
                    if (tar.hasClass("f-state-hover")) {
                        t.roll = false;
                    } else {
                        t.roll = true;
                    }
                });
            });

            //开始滚动
            t.rollInterval = setInterval(() => {
                if (!t.canroll) return;
                t.el.find(".f-grid-bodyct").find("table").eq(0).css({
                    "top": `${t.rolltop}px`,
                });
            }, 20);

            F.windowResize(function () {
                t.clearRoll();
                setTimeout(() => { t.rollData(); }, 100);
            });
        },
        //重置
        clearRoll() {
            let t = this;
            t.rollInterval = null;
            t.canroll = false;
            t.rolltop = 0;
            t.roll1.remove();
            t.roll2.remove();
            t.el.find(".f-grid-bodyct").find("table").eq(0).css({
                "top": `${t.rolltop}px`,
            });
        }
    });

    /**
    *
    * @param {any} params
    */
    function renderStep(params) {
        let t = this;
        let { columns } = t;
        var rowId = params.rowData.id;
        var renderer = params.renderer;
        const { rowValue, rowIndex, rowCls, rowAttrs } = params;
        let html = [];

        html.push(`<div class="f-step-card " data-step="${rowIndex}">`);

        html.push(`<div class="f-step-head">`);
        html.push(` <div class="f-step-icon">`);
        html.push(` <div class="f-step-num">`);
        html.push(` ${rowIndex + 1}`);
        html.push(` </div>`);
        html.push(` <div class="f-step-icon-finish f-iconfont-correct">`);
        html.push(` </div>`);
        html.push(` </div>`);
        html.push(` <div class="f-step-line">`);
        html.push(` </div>`);
        html.push(`</div>`);

        html.push(`<div class="f-step-main">`);
        html.push(` <div class="f-step-title">`);
        html.push(` ${rowValue.Title}`);
        html.push(` </div>`);
        html.push(` <div class="f-step-des">`);
        html.push(` ${rowValue.TextBody}`);
        html.push(` </div>`);
        html.push(`</div>`);

        html.push(`</div>`);
        return html.join("");
    }

    //
    F.Grid.prototype.__stepActive = -1;
    Object.defineProperty(F.Grid.prototype, "stepActive", {
        /**
         * 从0开始
         * @param {number} val
         */
        set(val) {
            //设置当前激活的 序号
            //无效的样式是 f-state-disabled
            //完成的样式是 f-step-finish
            //后面的 f-step-card 无效
            //当前的 f-step-line 无效
            //前面的 f-step-card 完成
            const t = this;
            let el = t.el.find(`.f-step-card[data-step="${val}"]`);
            //一共几步
            let count = t.el.find(`.f-step-card`).length;
            if (val < 0 || this.__stepActive == val) return;
            while (val > count) {
                val = val - count - 1;
            }
            //重置
            t.el.find(`.f-step-finish`).removeClass("f-step-finish");
            t.el.find(`.f-state-disabled`).removeClass("f-state-disabled");
            for (let i = val + 1; i < count; i++) {
                let nextel = t.el.find(`.f-step-card[data-step="${i}"]`);
                nextel.addClass("f-state-disabled");
            }
            for (let i = 0; i < val; i++) {
                t.el.find(`.f-step-card[data-step="${i}"]`).addClass("f-step-finish");
            }
            el.find(".f-step-line").addClass("f-state-disabled");
            this.__stepActive = val;
            this.trigger("stepChange", []);
        },
        get() {
            return this.__stepActive;
        }
    });
    //监听 showBody 控制是否显示明细
    F.Grid.prototype.__showBody = true;
    Object.defineProperty(F.Grid.prototype, "showBody", {
        /**
         * @param {boolean} val
         */
        set(val) {
            const t = this;
            let el = t.el.find(`.f-step-card .f-step-des`);
            if (!val) {
                el.addClass("f-hidden");
            } else {
                el.removeClass("f-hidden");
            }
            this.__showBody = val;
        },
        get() {
            return this.__showBody;
        }
    });
}

//表格列
if (F.GridColumn) {
    $.extend(F.GridColumn.prototype, {
        //在列表显示switch时 绘制text:是|否
        ShowSwitchText() {
            const t = this;
            const fun = () => {
                let el = $(`.f-grid-cell-${t.columnId}.f-grid-checkboxfield`).find("span.f-field-checkbox-switch-text");
                if (el && !el.hasClass("f-checkbox-text")) {
                    el.addClass('f-checkbox-text');
                }
            }
            //在框架会执行 doLayout，所以在这就不用了
            F.ui[t.parent.id].on("layout", () => { fun(); });
            return t;
        },

        //列表Check列控件的点击事件
        onCheckClick(fun) {
            const t = this;
            let checkboxSelector = `.f-grid-cell-${t.columnId} .f-grid-checkbox`;
            t.parent.el.on('click', checkboxSelector, function (event) {
                let cnode = $(this);
                let rowData = t.parent.getRowData(cnode.closest('.f-grid-row'));
                let isChecked = cnode.hasClass('f-checked');
                let _fun = new Function(`return ${fun};`)();
                _fun.apply(t, [isChecked, rowData, t.parent]);
            });
            return t;
        }
    });
}

//按钮
if (F.Button) {
    $.extend(F.Button.prototype, {
        showLoading() {
            let t = this;
            //找到已经有的图标
            t.iconel = t.el.find(".f-btn-inner i.f-btn-icon");
            if (t.iconel && t.iconel.length > 0) {
                //藏起来
                t.iconel.remove();
            } else {
                t.iconel = false;
                //如果没有图标 需要样式补位
                t.el.addClass(`${t.iconCls}-${t.iconAlign}`);
            }
            //show的时候需要通过图标位置判断是开头插入还是末尾插入
            t.addicon = $.fn.prepend;
            if (t.iconAlign == "bottom" || t.iconAlign == "right") {
                t.addicon = $.fn.append;
            }
            //插入一个 load图标
            t.addicon.apply(t.el.find(".f-btn-inner"),
                ['<i class="f-btn-icon f-icon f-iconfont f-iconfont-loading loading-iocn" style="display: inline-block;"></i>']);
            //不可选
            t.setEnabled(false);

            //通知爹 重置布局
            t.parent.doLayout();
            return t;
        },
        hideLoading() {
            let t = this;
            //删除 load图标
            t.el.find(".f-btn-inner i.f-btn-icon.loading-iocn").remove();
            if (t.iconel && t.iconel.length > 0) {
                //将原本的图标还原
                t.addicon.apply(t.el.find(".f-btn-inner"), [t.iconel]);
                t.iconel = false;
            } else {
                //删除补位演示
                t.el.removeClass(`${t.iconCls}-${t.iconAlign}`);
            }
            //可选
            t.setEnabled(true);
            //通知爹 重置布局
            t.parent.doLayout();
            return t;
        }
    });
}

//输入框
if (F.TextBox) {
    //重写前先拔下来
    if (!F.TextBox.prototype._getValue) {
        F.TextBox.prototype._getValue = F.TextBox.prototype.getValue;
    }
    //script 正则
    $.SCRIPT_REGEX = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
    //$.HTML_REGEX = /<[^<>]+?>/g;
    $.extend(F.TextBox.prototype, {
        //正则数组
        replaceRegex: [$.SCRIPT_REGEX, '<script>', '<\/script>'],
        //重写getValue 触发方法beforgetValue
        getValue: function () {
            var t = this;
            try {
                //先获取一遍
                var v = F.TextBox.prototype._getValue.call(t);
                //触发事件
                t.trigger('beforgetValue', [v, t]);
                //再取一遍
                v = F.TextBox.prototype._getValue.call(t);
                return v;
            }
            catch (ex) { return ""; }
        },
        setClear: function () {
            var t = this;
            if (!t.bodyEl) { return; }
            var icon = $('<div class="f-field-triggerbox-icons f-corner-all"></div>');
            icon.append('<i class="f-field-triggerbox-icon f-icon f-iconfont f-triggerbox-trigger1 f-triggericon-clear" style="display: inline-block;"></i>');
            icon.hide();
            t.bodyEl.after(icon);
            t.bodyEl.css('padding-right', '23px');
            icon.on('click', function () {
                t.clearValue();
                t.trigger("change");
            })
            t.on("change", function () {
                if (t.getValue() == '') {
                    icon.hide();
                } else if (!t.getReadonly()) {
                    icon.show();
                }
            })
            if (t.getValue() != '' && !t.getReadonly()) {
                icon.show();
            }
        },
        getReadonly() {
            const t = this;
            return t.bodyEl.is('[readonly]');
        }
    });
}

//展开控件 通用
if (F.TriggerBox) {
    $.extend(F.TriggerBox.prototype, {
        /**监听展开 触发open事件 本体，展开的el */
        listenerOpen() {
            const t = this;
            if (!t.Openlistener) {
                //监听的ID
                let article = document.getElementById(t.id);
                let observer = new MutationObserver(mutations => {
                    //当前控件
                    let el = $(mutations[0].target);
                    //打开了
                    if (el.hasClass("f-pop-opened")) {
                        t.trigger("open", [t, $(`[data-targetid='${t.id}']`)]);
                        //只执行一次 关闭监听
                        //observer.disconnect();
                    }
                });
                observer.observe(article, {
                    'attributeFilter': ['class'],
                    'attributes': true
                });
                //不要重复监听
                t.Openlistener = true;
            }
        }
    });
}

//时间控件
if (F.DatePicker) {
    $.extend(F.DatePicker.prototype, {
        //清除的图标
        setClear: function () {
            var t = this;
            var icon = t.el.find(".f-triggerbox-trigger1.f-triggericon-clear");
            icon.on('click', function () {
                t.clearValue();
                t.trigger("change");
            })
            t.on("change", function () {
                if (!t.getValue() || t.getValue() == '') {
                    icon.hide();
                } else if (!t.getReadonly()) {
                    icon.show();
                }
            })
            if (t.getValue() != '' && t.getValue() && !t.getReadonly()) {
                icon.show();
            }
        },
        /** 显示选择小时和分钟 */
        showTimeEx() {
            const t = this;
            t.listenerOpen();
            const onopen = (e, t, openel) => {
                t.openel = openel;
                t.renderTime();
                t.off('open', onopen);
            };
            t.on('open', onopen);
        },
        /**绘制小时和分钟 */
        renderTime() {
            const t = this;
            //绘小时和分钟的选择器
            let bodyheight = t.openel.find(".f-calendar-datepane .f-calendar-body.f-widget-content").height() + 10 + '';

            let temp = $("<div class='f-calendar-timepane'>");
            let header = $("<div class='f-calendar-header f-widget-header'><div class='f-calendar-time'>");
            header.children().eq(0).append(`<span class="hour"></span>:<span class="minute"></span>`);
            temp.append(header);
            let body = $("<div class='f-calendar-body f-widget-content'>");
            body.height(bodyheight);
            let table = $("<table class='f-calendar-float f-calendar-floattime f-widget-content f-calendar-float-column-2'>");
            let tr = $("<tbody><tr>");
            let td1inner = $("<td class='f-widget-content'><div class='f-calendar-float-td-inner'>");
            td1inner.height(bodyheight);
            let ul1 = $('<ul class="f-calendar-float-column-hour" style="width: 100%;">');//.padStart(2, '0')
            for (let i = 0; i < 24; i++) {
                let li = $(`<li><a class="">${(i + '').padStart(2, '0')}</a></li>`);
                ul1.append(li);
            }
            td1inner.children().eq(0).append(ul1);
            tr.children().eq(0).append(td1inner);

            let td2inner = $("<td class='f-widget-content f-last'><div class='f-calendar-float-td-inner'>");
            td2inner.height(bodyheight);
            let ul2 = $('<ul class="f-calendar-float-column-minute" style="width: 100%;">');
            for (let i = 0; i < 60; i++) {
                let li = $(`<li><a class="">${(i + '').padStart(2, '0')}</a></li>`);
                ul2.append(li);
            }
            td2inner.children().eq(0).append(ul2);
            tr.children().eq(0).append(td2inner);

            body.append(table);
            table.append(tr);
            temp.append(body);

            t.openel.find(".f-calendar-datetimepane").append(temp);
            //绘小时和分钟的选择器 结束

            //重新绘制底部
            let actions = t.openel.find(".f-calendar-footer.f-widget-header").find(".f-calendar-actions");
            console.log('actions>', actions);
            actions.css("textAlign", "right");

            //现在按钮
            let nowel = $("<a>");
            nowel.addClass("f-btn f-noselect f-state-default f-corner-all f-btn-small f-btn-icon-no f-cmp f-widget");
            nowel.css({ "margin-right": "5px", "display": "inline-block" });
            nowel.append('<span class="f-btn-inner"><span class="f-btn-text">现在</span></span>');

            //确定按钮
            let queding = $("<a>");
            queding.addClass("f-btn f-noselect f-state-default f-corner-all f-btn-small f-btn-icon-no f-cmp f-widget");
            queding.css({ "display": "inline-block" });
            queding.append('<span class="f-btn-inner"><span class="f-btn-text">确定</span></span>');

            actions.html('');
            actions.append(nowel);
            actions.append(queding);
            //重新绘制底部 结束

            //得到值
            const getvalue = (_v) => {
                let newdate;
                if (!_v) {
                    let date = F.formatDate("yyyy-MM-dd", t.getValue());
                    let hour = t.openel.find("span.hour").text();
                    let minute = t.openel.find("span.minute").text();
                    date += ` ${hour}:${minute}`;
                    newdate = F.parseDate("yyyy-MM-dd HH:mm", date);
                    return F.formatDate(t.format, newdate);
                } else {
                    return F.formatDate(t.format, _v);
                }
            };

            //现在
            nowel.on("click", () => {
                let newdate = new Date;
                let HH = F.formatDate("HH", newdate);
                let mm = F.formatDate("mm", newdate);
                t.sethour(HH, mm);
                t.setValue(getvalue(newdate));
                t.hidePopEl();
            });
            //确定
            queding.on("click", () => {
                t.setValue(getvalue());
                t.hidePopEl();
            });
            //阻止选择日期关闭
            t.on("select", function (e) {
                setTimeout(() => {
                    t.showPopEl();
                    t.setValue(getvalue());
                }, 0)
            });

            //设置初始值
            let v = t.getValue();
            let HH = F.formatDate("HH", v);
            let mm = F.formatDate("mm", v);
            t.sethour(HH, mm);
        },
        /** 设置小时和分钟*/
        sethour(hour, minute) {
            const t = this;
            let HH = (hour + '').padStart(2, '0');
            let mm = (minute + '').padStart(2, '0');

            //小时选中
            let clah = "f-calendar-float-column-hour";
            t.openel.find(`.${clah} a`).removeClass("f-state-active");
            t.openel.find(`.${clah} a`).each((i, h) => {
                if ($(h).text() == HH) {
                    $(h).addClass("f-state-active");
                }
            });
            t.openel.find("span.hour").text(HH);

            //小时滚动条
            let aH = t.openel.find(`.${clah} a.f-state-active`);
            let ahtop = aH.offset().top;
            let ahmain = aH.parent().parent().parent();
            ahmain.animate({ scrollTop: ahtop - ahmain.offset().top + ahmain.scrollTop() }, 80);

            //分钟选中
            let clam = "f-calendar-float-column-minute";
            t.openel.find(`.${clam} a`).removeClass("f-state-active");
            t.openel.find(`.${clam} a`).each((i, h) => {
                if ($(h).text() == mm) {
                    $(h).addClass("f-state-active");
                }
            });
            //分钟滚动条
            t.openel.find("span.minute").text(mm);
            let aM = t.openel.find(`.${clam} a.f-state-active`);
            let amtop = aM.offset().top;
            let ammain = aM.parent().parent().parent();
            ammain.animate({ scrollTop: amtop - ammain.offset().top + ammain.scrollTop() }, 80);
        }
    });
}

//下拉框
if (F.DropDownList) {
    $.extend(F.DropDownList.prototype, {
        popCheckbox: "f-field-dropdownlist-pop-checkbox",
        //多选时显示chekbox
        showSelectCheckBox() {
            const t = this;
            //如果不是多选 直接返回
            if (!t.multiSelect) { return; }
            t.ddlul = `ul.f-field-dropdownlist-pop[data-targetid='${t.id}']`;
            //监听的ID
            let article = document.getElementById(t.id);
            let observer = new MutationObserver(mutations => {
                //当前控件
                let el = $(mutations[0].target);
                //打开了
                if (el.hasClass("f-pop-opened")) {
                    let ddlul = $(t.ddlul);
                    ddlul.addClass(t.popCheckbox);
                    ddlul.find("li").each((i, e) => {
                        $(e).html(`<i class="f-icon f-iconfont f-checkbox"></i><span>${$(e).text()}</span>`);
                    });
                    let v = t.getValue();
                    checkboxByV(v);
                    //只执行一次 关闭监听
                    observer.disconnect();
                }
            });
            observer.observe(article, {
                'attributeFilter': ['class'],
                'attributes': true
            });
            t.on("select", (e, v) => {
                checkboxByV(v);
            });
            const checkboxByV = (v) => {
                let ddlul = $(t.ddlul);
                ddlul.find(`li i`).removeClass('f-checked');
                v.forEach(item => {
                    ddlul.find(`li[data-value='${item}'] i`).addClass('f-checked');
                });
            };
            return t;
        },
    });
}

//窗体
if (F.Window) {
    $.extend(F.Window.prototype, {
       
        //是否可关闭
        setClosable(b = true) {
            const t = this;
            let close = t.el.find(".f-panel-tools .f-tool-close");
            b ? close.fadeIn('fast') : close.fadeOut('fast');
            return t;
        }
    });
}

//页签
if (F.TabStrip) {
    $.extend(F.TabStrip.prototype, {
        animateChange() {
            const t = this;
            t.listenerOpen();
            t.on("beforTabChange", function (e, t, f, b, a) {
                let s = "right";
                if ($(`#${b}`).nextAll(`#${a}`).length == 0) {
                    s = "left";
                }
                f.ags1 = $(f.ags1);
                f.ags2 = $(f.ags2);
                f.ags1.removeClass("f-hidden-offsets");
                f.ags1.FineUIanimateCss(`f-slide-${s}-out`, function () {
                    f.ags1.addClass("f-hidden-offsets");
                });
                f.ags2.FineUIanimateCss(`f-slide-${s}-in`);
            })
        },
        listenerOpen() {
            const t = this;
            if (!t.Openlistener) {
                //监听的ID
                let article = $(`#${t.id}`).find(".f-tabstrip-body")[0];
                if (!t.beforTabChange) {
                    t.beforTabChange = {}
                };
                let observer = new MutationObserver(mutations => {
                    mutations.forEach(function (mutation) {
                        let tar = $(mutation.target);
                        let tabid = tar.attr("data-tabid");
                        let newclas = tar.attr("class");
                        let cls = "f-hidden-offsets";
                        if (mutation.oldValue
                            && mutation.oldValue.indexOf(cls) < 0
                            && newclas.indexOf(cls) >= 0) {
                            t.beforTabChange.ags1 = tar[0];
                        }
                        if (mutation.oldValue
                            && mutation.oldValue.indexOf(cls) >= 0
                            && newclas.indexOf(cls) < 0) {
                            t.beforTabChange.ags2 = tar[0];
                            t.trigger("beforTabChange",
                                [t, t.beforTabChange, t.beforTabChange.ags1.id, t.beforTabChange.ags2.id]);
                        }
                    });
                });
                observer.observe(article, {
                    'childList': true,
                    'attributeFilter': ['class'],
                    'attributes': true,
                    'attributeOldValue': true,
                    'subtree': true
                });
                //不要重复监听
                t.Openlistener = true;
            }
        },
        //当标题在左右时 让位置和图标竖向排列
        titleVertical() {
            const t = this;
            let els = t.el.find('a.f-tab-header .f-panel-title-text');
            $.each(els, function (i, el) {
                let str = $(el).text();
                let spanstr = str.split('').map(s => `<span style="transform: rotate(270deg);display: inline-block;">${s}</span>`);
                spanstr = spanstr.join("") + "&nbsp;&nbsp;&nbsp;";
                $(el).html(spanstr);
            });
            let elsi = t.el.find('.f-panel-tools a.f-tool i.f-tool-icon');
            $.each(elsi, function (i, el) {
                $(el).css({ "transform": "rotate(270deg)", "display": "inline-block" });
            });
            t.doLayout();
            return t;
        },
    });
}

//控件基类
if (F.Container) {
    const _showLoading = F.Container.prototype.showLoading;
    const _hideLoading = F.Container.prototype.hideLoading;
    //console.log('_showLoading>', _showLoading);
    $.extend(F.Container.prototype, {
        showLoading() {
            let t = this;
            t.el.addClass("showLoading");
            _showLoading.call(t);
            $('.f-loading-img').html('<i class="f-icon f-icon-refresh loading-iocn"></i>')
        },
        hideLoading() {
            let t = this;
            _hideLoading.call(t);
            t.el.removeClass("showLoading");
        },
        /**开启监听，注意只能开启一次
         * 默认监听 class 默认开启old值 默认监听子集
         * */
        openObserver(opt = {}) {
            let t = this;
            if (!t.Observered) {
                t.Observered = true;
                let def = {
                    'childList': true,//子集
                    'attributeFilter': ['class'],//监听的属性
                    'attributes': true,//
                    'attributeOldValue': true,//监听old值
                    'subtree': true//子集
                };
                opt = Object.assign(def, opt);
                let observer = new MutationObserver(mutations => {
                    t.trigger("observer", [mutations]);
                });
                let article = document.getElementById(t.id);
                observer.observe(article, opt);
            }
        }
    });
}

//按钮基类
if (F.Component) {
    $.extend(F.Component.prototype, {
        /**
         * 绑定按键
         * @param {any} key
         * @param {any} fun
         */
        bindkey(key, fun, settext) {
            const t = this;
            if (t.setText && settext) {
                let span = $(`<span class="f-btn-inner" style="margin-left: 5px;"><span class="f-btn-text f-state-active" style="padding: 0px 4px;">(${key})</span></span>`);
                t.el.find(".f-btn-inner").eq(0).after(span);
            }
            return window.top.addbindkey(key, fun, t);
        }
    });
}
//eCharts
if (!F.eChart) {
    //传入#id
    F.eChart = (render, opt) => {
        if (render.indexOf('#') != 0) { render = `#${render}`; };
        const themeName = F.cookie('Theme');
        let _echart = {};
        if (themeName == "Eggplant") {
            _echart = echarts.init($(render)[0], 'Mydark');
        } else {
            _echart = echarts.init($(render)[0]);
        }
        _echart.setOption(opt);
        F.windowResize(function () {
            _echart.resize();
        });
        F.ui[render.replace("#", "")] = _echart;
        return _echart;
    }
}

//其他通用
(function () {
    doCallback = function (fn, args) {
        return fn.apply(this, args);
    }
    // 通知框
    notifyEx = function (msg) {
        F.notify({
            message: msg,
            messageIcon: 'information',
            target: '_top',
            header: false,
            displayMilliseconds: 3 * 1000,
            positionX: 'center',
            positionY: 'top'
        });
    }

    //确认提示
    confirmEx = function (mag, okfun) {
        var t = F.confirm({
            message: mag,
            messageIcon: 'question',
            ok: function () {
                // 触发后台事件
                doCallback(okfun, []);
            }
        });
        let btns = t.bars[0].items;
        btns[0].el.addClass("f-btn-Primary");
        btns[1].el.addClass("f-btn-Default");
    }

    PConfirmEx = function (mag) {
        return new Promise((r, v) => {
            F.confirm({
                message: mag,
                messageIcon: 'question',
                closable: false,
                ok: function () {
                    r({ type: "ok" });
                },
                cancel() {
                    r({ type: "cancel" });
                }
            });
        })
    }

    /**
     * 返回Promise使前台可以同步
     * @param {Object} opts 只接收Obj数据
     */
    F.doPostBackP = (opts) => {
        const _complete = opts.complete;
        const autoLoading = opts.autoLoading;
        const autoEnabled = opts.autoEnabled;
        const guid = GetGuid();
        opts.complete = (...coms) => {
            if (autoLoading) {
                autoLoading.split(",").forEach(id => {
                    if (F.ui[id] && F.ui[id].hideLoading) {
                        F.ui[id].hideLoading();//showLoading
                    }
                });
            }
            if (autoEnabled) {
                autoEnabled.split(",").forEach(id => {
                    if (F.ui[id] && F.ui[id].setEnabled) {
                        F.ui[id].setEnabled(true);//hideLoading
                    }
                });
            }
            _complete && _complete.apply(this, [...coms, guid]);
        };
        return new Promise(r => {
            //将r放到指定id中 参数args由后台赋值
            F.doPostBack[guid] = r;
            if (!opts.params) {
                opts.params = {}
            }
            //后台body中接收postGUID 参照UIdoPostBack
            opts.params.postGUID = guid;
            if (autoLoading) {
                autoLoading.split(",").forEach(id => {
                    if (F.ui[id] && F.ui[id].showLoading) {
                        F.ui[id].showLoading();//hideLoading
                    }
                });

                opts.enableAjaxLoading = false;
            }
            if (autoEnabled) {
                autoEnabled.split(",").forEach(id => {
                    if (F.ui[id] && F.ui[id].setEnabled) {
                        F.ui[id].setEnabled(false);//hideLoading
                    }
                });
            }
            //执行原始回发
            F.doPostBack(opts);
        });
    }

    //新增 修改 删除 由后台自动引用，通过传入的GirdID执行前台或者后台方法
    //新增
    GridAdd_click = function (gridid) {
        eval("var fun;try{fun=" + gridid + "new_Click;}catch(ex){}");
        if (fun) {
            fun(F.ui[gridid]);
        } else {
            F.ui[gridid].showEdit();
        }
    };
    //修改
    GridEdit_click = function (gridid) {
        eval("var fun;try{fun=" + gridid + "edit_Click;}catch(ex){}");
        var selectids = F.ui[gridid].getSelectedRows();
        if (selectids.length != 1) {
            notifyEx("请选择一行进行编辑");
            return;
        }
        if (fun) {
            fun(F.ui[gridid], selectids[0]);
        } else {
            F.ui[gridid].showEdit(true);
        }
    }
    //删除
    GridDel_click = function (pburl, gridid) {
        //不跳过提示的删除
        eval("var fun;try{fun=" + gridid + "delete_Click;}catch(ex){}");
        //跳过提示的删除 Del_Click
        eval("var funDel;try{funDel=" + gridid + "Del_Click;}catch(ex){}");
        var selectids = F.ui[gridid].getSelectedRows();
        if (selectids.length == 0) {
            notifyEx("请选择一行进行编辑");
            return;
        }
        if (funDel) {
            funDel(F.ui[gridid], selectids);
            return;
        }
        confirmEx("是否删除选中项", function () {
            if (fun) {
                fun(F.ui[gridid], selectids);
            } else {
                eval('var href = window.pburl;');
                if (!pburl && href) {
                    F.doPostBack(href + "/" + gridid + 'Del_Click', {
                        id: selectids,
                        fields: F.ui[gridid].fields,
                        complete() {
                            F.ui[gridid].clearSelection();
                            F.ui[gridid].deleteSelectedRows();
                        }
                    });
                } else {
                    F.doPostBack(pburl + "/" + gridid + 'Del_Click', {
                        id: selectids,
                        fields: F.ui[gridid].fields
                    });
                }
            }
        });
    }
    renderEx = function (fn) {
        //创建模板
        let model = {
            /**
             * 按钮
             * @param {Object} opt {id,text必填;icon图标 拼接 f-;beforRender;click;hidetype[visibility]}
             */
            btn(opt) {
                const _btn = (_opt = opt) => {
                    //按钮和text 默认 是value
                    let oldid = _opt.id;
                    _opt.id = `${_opt.id}_${this.params.rowId}_${this.params.columnId}`;
                    _opt.text = _opt.text || this.value;

                    //绘制按钮
                    _opt.el = $(`<a id="${_opt.id}">`).addClass("f-btn f-state-default f-btn-Default");
                    _opt.el.attr("data-type", oldid);

                    //<i class="f-btn-icon f-icon f-icon-pencil" style="display: inline-block;color: #3d80b3;"></i>
                    if (_opt.icon) {
                        _opt.el.append(`<i class="f-btn-icon f-icon f-icon-${_opt.icon}" style="display: inline-block;color: #409eff;"></i>`);
                        //如果有图标 btn缩小
                        _opt.el.css("padding-left", '5px');
                    }
                    //触发绘制前方法
                    let b = _opt.beforRender && _opt.beforRender.apply(this, [_opt]);
                    _opt.el.append(`<span>${_opt.text}</span>`);

                    //注册按钮事件 注意由于还没有绘制所以只能延迟
                    (b || F.isEMP(b)) && _opt.click && setTimeout(() => {
                        //可以自己加入其他事件
                        $('#' + _opt.id).on('click', function () {
                            doCallback(_opt.click, [_opt]);
                        })
                    }, 0);

                    //返回html
                    if (b || F.isEMP(b)) {
                        return _opt.el[0].outerHTML;
                    } else if (_opt.hidetype && _opt.hidetype == 'visibility') {
                        _opt.el.css("visibility", 'hidden');
                        return _opt.el[0].outerHTML;
                    }
                    else {//如果绘制的方法回发fasle就没有html
                        return "";
                    }
                }

                //如果不是数组
                if (!F.isARR(opt)) {
                    return _btn();
                } else {
                    //如果是数组 加入到组里 加个间距的样式
                    let btndiv = $('<div class="GridRowBtns">');

                    opt.forEach(item => {
                        btndiv.append(_btn(item));
                    })
                    //返回html
                    return btndiv[0].outerHTML;
                }
            },
            //返回是否
            bool() {
                return this.value == 1 ? '是' : '否';
            },
            //性别
            gender() {
                return this.value == 1 ? '男' : '女';
            },
            //a标签
            link(opt) {
                const _link = (_opt = opt) => {
                    //按钮和text 默认 是value
                    _opt.id = `${_opt.id}_${this.params.rowId}_${this.params.columnId}`;
                    _opt.text = _opt.text || this.value;

                    //绘制按钮
                    _opt.el = $(`<a id="${_opt.id}">`).addClass("grid-row-link").append(`<span>${_opt.text}</span>`);

                    //触发绘制前方法
                    let b = _opt.beforRender && _opt.beforRender.apply(this, [_opt]);

                    //注册按钮事件 注意由于还没有绘制所以只能延迟
                    _opt.click && setTimeout(() => {
                        //可以自己加入其他事件
                        $('#' + _opt.id).on('click', function () {
                            doCallback(_opt.click, [_opt]);
                        })
                    }, 0);

                    //返回html
                    if (b || F.isEMP(b)) {
                        return _opt.el[0].outerHTML;
                    }
                    else {//如果绘制的方法回发fasle就没有html
                        return "";
                    }
                }

                //如果不是数组
                if (!F.isARR(opt)) {
                    return _link();
                } else {
                    //如果是数组 加入到组里 加个间距的样式
                    let btndiv = $('<div class="GridRowBtns">');

                    opt.forEach(item => {
                        btndiv.append(_link(item));
                    })
                    //返回html
                    return btndiv[0].outerHTML;
                }
            }
        }
        /*柯里化
         * 最后还是返回一个方法，
         * 这个方法将被正常的RendererFunction执行，
         * 但是扩展了一个参数
         * 懂的都懂
         * */
        return function (value, params) {
            //先给model赋值
            Object.assign(model, {
                value,
                params,
            });

            //再本示例中触发的是renderBtns方法 自己缕一缕，
            return doCallback(fn, [value, params, model, this]);
        }

        //apply的写法
        //doCallback = function (fn, args) {
        //    return fn.apply(this, args);
        //}
    }

    /**
     * 设置url参数
     */
    setIframeUrl = (url, data) => {
        if (url.indexOf('?') < 0) {
            url += "?_reg=" + Math.random();
        }
        else if (url.indexOf('_reg') < 0) {
            url += "&_reg=" + Math.random();
        }
        let MenuId = F.queryString("MenuId");
        if (data) {
            if (!data.MenuId) data.MenuId = MenuId;
            if (F.isARR(data)) {
                data.forEach(function (d) {
                    url += "&" + d;
                })
            } else if (F.isPOBJ(data)) {
                Object.keys(data).forEach(item => {
                    url += `&${item}=${data[item]}`;
                })
            } else {
                url += "&" + data;
            }
        }
        return url;
    }

    //导航和页签控件关联
    F.initNavBarTabStrip = (navBar, mainTabStrip, option) => {
        //navBar的items,找到Button的menu下的items，类型是MenuItem href是链接地址
        navBar.items.forEach((item) => {
            if (item.type == "button" && item.menu && item.menu.items) {
                item.menu.items.forEach((menuItem) => {
                    if (menuItem.type == "menuitem" && menuItem.href) {
                        console.log('menuItem>', menuItem);
                        menuItem.el.find("a.f-menu-item-text").css("pointer-events", "none");
                        menuItem.on("beforeclick", () => {
                            mainTabStrip.addTab({
                                id: 'tab_' + menuItem.id,
                                iframe: true,
                                iframeUrl: menuItem.href.replace('~', ".."),
                                title: menuItem.text,
                                closable: true
                            }, true);
                            item.menu.hide();
                            return false;
                        })
                    }
                })
            }
        })
    }

    $.fn.extend({
        //设置动画效果
        //animationName 效果样式名称
        //fun 完成动画后回调
        animateCss: function (animationName, fun) {
            var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';
            $(this).addClass('animated ' + animationName).one(animationEnd, function () {
                if (fun) {
                    fun();
                }
                $(this).removeClass('animated ' + animationName);
            });
        },
        //设置FineUI原生 动画效果
        //animationName 效果样式名称
        //fun 完成动画后回调
        FineUIanimateCss: function (animationName, fun) {
            var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';
            $(this).addClass('f-anim ' + animationName).one(animationEnd, function () {
                if (fun) {
                    fun();
                }
                $(this).removeClass('f-anim ' + animationName);
            });
        }
    });
    //const fetchPage = new AsyncFunction("url", "return await fetch(url);");


    /**生成GUID */
    GetGuid = () => {
        const S4 = () => (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
        return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
    }
})(F)
